package mammuthus.slave

import scala.sys.process._
import net.csdn.common.logging.Loggers
import java.io.{File, RandomAccessFile}


/**
 * 2/2/15 WilliamZhu(allwefantasy@gmail.com)
 */
object ShellCommand extends TFileWriter {
  val logger = Loggers.getLogger(classOf[ShellCommand])

  def upgrade(projectName: String, tag: String, f: String => String) = {
    val hostName = s"hostname".!!
    try {
      val homePath = s"/data/web/applications/${projectName}"
      val pidPath = s"$homePath/current/application.pid"
      val logPath = s"$homePath/current/logs/csdn_search.log"
      s"$homePath/bin/deploy.sh upgrade $tag" lines_! ProcessLogger {
        k => f(s"$hostName=>\n $k")
      }
      val pid = s"cat $pidPath".!!
      val pidInfo = s"ps -ef |grep -v grep |grep $pid".!!
      f(s"$hostName=>\n进程信息: $pidInfo")
      val logInfo = s"tail -n300 $logPath".!!
      f(s"$hostName=>\n日志文件信息300行: $logInfo")
    } catch {
      case e: Exception => f(s"$hostName execute fail")
    }
  }

  def exec(shellStr: String) = {
    logger.debug("shell " + shellStr)
    val fileName = System.currentTimeMillis() + "_" + Math.random() + ".sh"
    writeToFile("/tmp/" + fileName, "#!/bin/bash\n" + shellStr)
    logger.debug(s"chmod u+x /tmp/$fileName")
    s"chmod u+x /tmp/$fileName".!
    logger.debug(s"/bin/bash /tmp/$fileName")
    val result = s"/bin/bash /tmp/$fileName".!!.trim
    logger.debug(s"rm /tmp/$fileName")
    s"rm /tmp/$fileName".!
    result
  }

  /*
    暂时没有去实现超时
   */
  def execWithExitValue(shellStr: String,timeout:Long=InteractiveShellCommand.defaultTimeOut) = {
    val out = new StringBuilder
    val err = new StringBuilder
    val et = ProcessLogger(
      line => out.append(line+"\n"),
      line => err.append(line+"\n"))
    logger.debug("shell " + shellStr)
    val fileName = System.currentTimeMillis() + "_" + Math.random() + ".sh"
    writeToFile("/tmp/" + fileName, "#!/bin/bash\n" + shellStr)
    logger.debug(s"chmod u+x /tmp/$fileName")
    s"chmod u+x /tmp/$fileName".!
    logger.debug(s"/bin/bash /tmp/$fileName")
    val pb = Process(s"/bin/bash /tmp/$fileName")
    val exitValue = pb ! et
    s"rm /tmp/$fileName".!
    logger.debug(s"rm /tmp/$fileName")
    (exitValue, err.toString().trim, out.toString().trim)
  }


  def progress(filePath: String, offset: Long, size: Int): (Long, String, Long) = {
    if (!new File(filePath).exists()) return (-1, "", 0)

    val fr = new RandomAccessFile(filePath, "r")
    if (fr.length() <= offset) {
      fr.close()
      return (-1, "", 0)
    }
    try {
      val temp = 4 * 1024 //if (fr.length() > 4 * 1024) 4 * 1024 else 0
      var newSize:Long = if(size <= 0 || size > 1024 * 1024) temp else size
      val newOffset = if (offset == -1 && fr.length() > temp) fr.length() - temp else if(offset == -1) 0 else offset
      fr.seek(newOffset)
      if(newOffset + newSize >= fr.length()) newSize = fr.length() - newOffset
      val bytes = new Array[Byte](newSize.toInt)
      fr.readFully(bytes)
      (fr.getFilePointer, new String(bytes, "UTF-8"), fr.length())
    } finally fr.close()

  }


}

class ShellCommand
